package com.xiaotu.handler;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.xiaotu.dto.BattleBindRoomDto;
import com.xiaotu.service.redission.RedissionService;
import com.xiaotu.service.redission.impl.RedissionServiceImpl;
import com.xiaotu.util.SpringUtil;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;

@Slf4j
@ServerEndpoint("/battleSocket/{battleBindRoom}")
@Component
@Data
@RequiredArgsConstructor
public class BattleHandler extends BasicHandler {

    private Session session;

    private Integer playerId;

    /**
     * 连接建立成功调用的方法
     *
     * @param session 链接session
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("battleBindRoom") String battleBindRoom) {
        this.session = session;
        if (StrUtil.isNotEmpty(battleBindRoom)) {
            BattleBindRoomDto battleBindRoomDto = JSONUtil.toBean("{" + battleBindRoom + "}", BattleBindRoomDto.class);
            Map<String, Object> userProperties = this.session.getUserProperties();
            userProperties.put("roomId", battleBindRoomDto.getRoomId());
            userProperties.put("playerId", battleBindRoomDto.getPlayerId());
            userProperties.put("this", this);
            this.playerId = battleBindRoomDto.getPlayerId();
            userProperties.put("camp", battleBindRoomDto.getCamp());
            if (battleBindRoomDto.getMode() == 1) {

            } else if (battleBindRoomDto.getMode() == 2) {
                battleCache.joinRoom(battleBindRoomDto.getRoomId(), battleBindRoomDto.getCapacity(), this.session);
            }
        }
        log.debug("链接成功");
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 消息内容
     * @param session session
     */
    @OnMessage
    public void onMessage(String message, Session session) throws JsonProcessingException {
        log.debug("websocket连接onMessage。{},{},{}", message, this.toString(), session.getId());
        if (StrUtil.isNotEmpty(message)) {
            Map messageType = JSONUtil.toBean(message, Map.class);
            String oldToken = messageType.get("authorization").toString();
            String phone = messageType.get("phone").toString();
            if (!validOldToken(phone, oldToken)) {
                oldTokenInvalidMessage(Integer.valueOf(messageType.get("roomId").toString()), session);
                return;
            }
            Integer type = Integer.parseInt(messageType.get("messageType").toString());
            if (type == 1) {
                transferCoordinateMessage(this.session, message);
            } else if (type == 2) {
                transferTrapCoordinateMessage(message, session);
            } else if (type == 3) {
                //正常获胜之后的操作
                winnerGameAfterMessage(session, message);
            } else if (type == 4) {
                //通知对方已认输 、通知对方求、通知对方是否同意求和
                noticeAnotherPlayer(Integer.parseInt(messageType.get("roomId").toString()), session, messageType.get("messageContent").toString());
            } else if (type == 5) {
                //再来一局请求
                gameAgainReq(Integer.parseInt(messageType.get("roomId").toString()), session, messageType.get("messageContent").toString());
            } else if (type == 6) {
                //人机对战请求
                manMachineReq(Integer.parseInt(messageType.get("roomId").toString()));
            }
        }
    }

    /**
     * 发生异常时的处理
     *
     * @param session   客户端session
     * @param throwable session
     */
    @OnError
    public void onError(Session session, Throwable throwable) {
        if (this.session != null && this.session.isOpen()) {
            log.error("websocket连接onError。inputSession：{}-localSession：{}", session.getId(), this.toString(), throwable);
            this.close(session);
        } else {
            log.debug("已经关闭的websocket连接发生异常！inputSession：{}-localSession：{}", session.getId(), this.toString(), throwable);
        }
        //通知对方
        noticeAnotherPlayer(session);
        //退出房间
        battleCache.leaveRoom(Integer.parseInt(session.getUserProperties().get("roomId").toString()), session);
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session) {
        log.debug("websocket连接onClose。{}", this);
        //通知对方
        noticeAnotherPlayer(session);
        //退出房间
        battleCache.leaveRoom(Integer.parseInt(session.getUserProperties().get("roomId").toString()), session);
        //然后关闭
        close(session);
    }

}
